﻿import pygame
import sys
import math
from pygame.locals import *

# 初始化 Pygame
pygame.init()

# 屏幕设置
WIDTH, HEIGHT = 1000, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("勾股定理原理动画演示")

# 颜色定义
BACKGROUND = (25, 30, 40)
TEXT_COLOR = (220, 220, 220)
HIGHLIGHT = (255, 215, 0)
TRIANGLE_COLOR = (70, 170, 220)
SQUARE_A_COLOR = (220, 100, 100, 180)
SQUARE_B_COLOR = (100, 220, 100, 180)
SQUARE_C_COLOR = (100, 100, 220, 180)
GRID_COLOR = (60, 70, 90)
WATER_COLOR = (100, 200, 255, 150)
ANIMATION_COLOR = (255, 150, 50)

# 字体
title_font = pygame.font.SysFont("simhei", 48, bold=True)
subtitle_font = pygame.font.SysFont("simhei", 32)
text_font = pygame.font.SysFont("simhei", 24)
small_font = pygame.font.SysFont("simhei", 18)
formula_font = pygame.font.SysFont("simhei", 36, bold=True)  # 添加缺失的字体定义

# 时钟
clock = pygame.time.Clock()
FPS = 60

# 勾股定理演示类
class PythagoreanTheorem:
    def __init__(self):
        self.stage = 0  # 0: 初始, 1: 三角形, 2: 正方形, 3: 切割, 4: 重组, 5: 完成
        self.progress = 0
        self.a = 200  # 直角边a长度
        self.b = 150  # 直角边b长度
        self.c = math.sqrt(self.a**2 + self.b**2)  # 斜边c长度
        self.center_x = WIDTH // 2
        self.center_y = HEIGHT // 2
        self.triangle_points = []  # 三角形顶点
        self.squares = []  # 正方形
        self.pieces = []  # 切割后的图形
        self.animation_pieces = []  # 动画中的图形
        self.water_level = 0
        self.water_filling = False
        self.create_shapes()
        
    def create_shapes(self):
        # 创建三角形
        self.triangle_points = [
            (self.center_x, self.center_y),  # 直角顶点
            (self.center_x + self.a, self.center_y),  # a边顶点
            (self.center_x, self.center_y - self.b)   # b边顶点
        ]
        
        # 创建三个正方形
        # a边正方形
        self.squares.append({
            "points": [
                (self.center_x, self.center_y),
                (self.center_x + self.a, self.center_y),
                (self.center_x + self.a, self.center_y + self.a),
                (self.center_x, self.center_y + self.a)
            ],
            "color": SQUARE_A_COLOR,
            "label": f"a² = {self.a**2}"
        })
        
        # b边正方形
        self.squares.append({
            "points": [
                (self.center_x, self.center_y),
                (self.center_x, self.center_y - self.b),
                (self.center_x - self.b, self.center_y - self.b),
                (self.center_x - self.b, self.center_y)
            ],
            "color": SQUARE_B_COLOR,
            "label": f"b² = {self.b**2}"
        })
        
        # c边正方形
        c_square_points = [
            (self.center_x + self.a, self.center_y),
            (self.center_x, self.center_y - self.b),
            (self.center_x - self.b, self.center_y - self.b + self.a),
            (self.center_x + self.a - self.b, self.center_y + self.a)
        ]
        self.squares.append({
            "points": c_square_points,
            "color": SQUARE_C_COLOR,
            "label": f"c² = {self.c**2:.0f}"
        })
        
        # 创建切割后的图形
        self.pieces = []
        # 切割a²正方形
        self.pieces.append({
            "points": [
                (self.center_x, self.center_y),
                (self.center_x + self.a, self.center_y),
                (self.center_x + self.a, self.center_y + self.a),
                (self.center_x, self.center_y + self.a)
            ],
            "color": SQUARE_A_COLOR,
            "target": c_square_points
        })
        
        # 切割b²正方形
        self.pieces.append({
            "points": [
                (self.center_x, self.center_y),
                (self.center_x, self.center_y - self.b),
                (self.center_x - self.b, self.center_y - self.b),
                (self.center_x - self.b, self.center_y)
            ],
            "color": SQUARE_B_COLOR,
            "target": c_square_points
        })
        
        # 复制一份用于动画
        self.animation_pieces = [piece.copy() for piece in self.pieces]
    
    def next_stage(self):
        if self.stage < 5:
            self.stage += 1
            self.progress = 0
            if self.stage == 4:
                self.water_filling = True
                self.water_level = 0
    
    def update(self):
        if self.stage == 4 and self.water_filling:
            self.water_level += 1
            if self.water_level > 100:
                self.water_filling = False
                self.progress = 1.0
        
        if self.stage == 3 and self.progress < 1.0:
            self.progress += 0.01
            if self.progress > 1.0:
                self.progress = 1.0
                
            # 更新切割动画
            for i, piece in enumerate(self.animation_pieces):
                # 计算中间位置
                start_points = self.pieces[i]["points"]
                target_points = self.squares[2]["points"]
                
                # 计算旋转和平移后的位置
                animated_points = []
                for j in range(len(start_points)):
                    start_x, start_y = start_points[j]
                    target_x, target_y = target_points[j]
                    
                    # 根据进度插值
                    x = start_x + (target_x - start_x) * self.progress
                    y = start_y + (target_y - start_y) * self.progress
                    animated_points.append((x, y))
                
                piece["points"] = animated_points
    
    def draw(self, surface):
        # 绘制背景
        surface.fill(BACKGROUND)
        
        # 绘制标题
        title = title_font.render("勾股定理原理动画演示", True, TEXT_COLOR)
        surface.blit(title, (WIDTH // 2 - title.get_width() // 2, 20))
        
        # 绘制公式
        formula_text = formula_font.render(f"a² + b² = c²   =>   {self.a}² + {self.b}² = {self.c:.1f}²", True, HIGHLIGHT)
        surface.blit(formula_text, (WIDTH // 2 - formula_text.get_width() // 2, 80))
        
        # 绘制当前阶段说明
        stage_texts = [
            "1. 绘制直角三角形",
            "2. 在三条边上构建正方形",
            "3. 切割两个小正方形",
            "4. 重组到斜边正方形中",
            "5. 面积相等证明定理"
        ]
        
        for i, text in enumerate(stage_texts):
            color = HIGHLIGHT if i == self.stage - 1 else TEXT_COLOR
            text_surf = text_font.render(text, True, color)
            surface.blit(text_surf, (50, 130 + i * 30))
        
        # 绘制三角形
        if self.stage >= 1:
            pygame.draw.polygon(surface, TRIANGLE_COLOR, self.triangle_points)
            pygame.draw.polygon(surface, (255, 255, 255), self.triangle_points, 2)
            
            # 标记直角
            pygame.draw.arc(surface, HIGHLIGHT, 
                           (self.center_x - 20, self.center_y - 20, 40, 40), 
                           math.radians(0), math.radians(90), 2)
            
            # 标记边长
            a_text = small_font.render(f"a = {self.a}", True, TEXT_COLOR)
            b_text = small_font.render(f"b = {self.b}", True, TEXT_COLOR)
            c_text = small_font.render(f"c = {self.c:.1f}", True, TEXT_COLOR)
            
            surface.blit(a_text, (self.center_x + self.a/2 - 20, self.center_y + 10))
            surface.blit(b_text, (self.center_x - 50, self.center_y - self.b/2))
            
            # 计算斜边标签位置
            c_x = self.center_x + self.a/2 - self.b/4
            c_y = self.center_y - self.b/2 + self.a/4
            surface.blit(c_text, (c_x, c_y))
        
        # 绘制正方形
        if self.stage >= 2:
            for square in self.squares:
                # 创建半透明表面
                square_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
                pygame.draw.polygon(square_surface, square["color"], square["points"])
                surface.blit(square_surface, (0, 0))
                
                pygame.draw.polygon(surface, (255, 255, 255), square["points"], 2)
                
                # 绘制标签
                if "label" in square:
                    label = small_font.render(square["label"], True, TEXT_COLOR)
                    # 计算中心点
                    center_x = sum(p[0] for p in square["points"]) / len(square["points"])
                    center_y = sum(p[1] for p in square["points"]) / len(square["points"])
                    surface.blit(label, (center_x - label.get_width()//2, center_y - label.get_height()//2))
        
        # 绘制切割动画
        if self.stage == 3:
            for piece in self.animation_pieces:
                # 创建半透明表面
                piece_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
                pygame.draw.polygon(piece_surface, piece["color"], piece["points"])
                surface.blit(piece_surface, (0, 0))
                
                pygame.draw.polygon(surface, (255, 255, 255), piece["points"], 2)
        
        # 绘制重组后的正方形
        if self.stage >= 4:
            # 创建半透明表面
            square_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
            pygame.draw.polygon(square_surface, SQUARE_C_COLOR, self.squares[2]["points"])
            surface.blit(square_surface, (0, 0))
            
            pygame.draw.polygon(surface, (255, 255, 255), self.squares[2]["points"], 2)
            
            # 绘制标签
            label = small_font.render(f"c² = {self.c**2:.0f}", True, TEXT_COLOR)
            center_x = sum(p[0] for p in self.squares[2]["points"]) / len(self.squares[2]["points"])
            center_y = sum(p[1] for p in self.squares[2]["points"]) / len(self.squares[2]["points"])
            surface.blit(label, (center_x - label.get_width()//2, center_y - label.get_height()//2))
            
            # 绘制填充动画
            if self.water_filling:
                water_points = [
                    (self.squares[2]["points"][0][0], self.squares[2]["points"][0][1] + self.water_level),
                    (self.squares[2]["points"][1][0], self.squares[2]["points"][1][1] + self.water_level),
                    (self.squares[2]["points"][2][0], self.squares[2]["points"][2][1] + self.water_level),
                    (self.squares[2]["points"][3][0], self.squares[2]["points"][3][1] + self.water_level)
                ]
                
                # 创建半透明表面
                water_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
                pygame.draw.polygon(water_surface, WATER_COLOR, water_points)
                surface.blit(water_surface, (0, 0))
        
        # 绘制证明结果
        if self.stage == 5:
            proof_y = HEIGHT - 150
            proof_title = subtitle_font.render("证明完成:", True, HIGHLIGHT)
            surface.blit(proof_title, (WIDTH // 2 - proof_title.get_width() // 2, proof_y))
            
            proof_text = text_font.render(f"a² + b² = {self.a**2} + {self.b**2} = {self.a**2 + self.b**2}", True, TEXT_COLOR)
            surface.blit(proof_text, (WIDTH // 2 - proof_text.get_width() // 2, proof_y + 50))
            
            proof_text2 = text_font.render(f"c² = ({self.c:.1f})² = {self.c**2:.0f}", True, TEXT_COLOR)
            surface.blit(proof_text2, (WIDTH // 2 - proof_text2.get_width() // 2, proof_y + 80))
            
            result_text = subtitle_font.render(f"a² + b² = c²", True, HIGHLIGHT)
            surface.blit(result_text, (WIDTH // 2 - result_text.get_width() // 2, proof_y + 120))
        
        # 绘制控制说明
        controls = [
            "空格键: 下一步演示",
            "R键: 重置演示",
            "↑/↓: 调整a边长度",
            "←/→: 调整b边长度"
        ]
        
        for i, text in enumerate(controls):
            control_text = text_font.render(text, True, TEXT_COLOR)
            surface.blit(control_text, (WIDTH - control_text.get_width() - 20, HEIGHT - 150 + i * 30))

# 主函数
def main():
    demo = PythagoreanTheorem()
    
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
            elif event.type == KEYDOWN:
                if event.key == K_SPACE:
                    demo.next_stage()
                elif event.key == K_r:
                    demo = PythagoreanTheorem()
                elif event.key == K_UP:
                    demo.a += 10
                    demo = PythagoreanTheorem()  # 重置以应用新尺寸
                elif event.key == K_DOWN and demo.a > 50:
                    demo.a -= 10
                    demo = PythagoreanTheorem()
                elif event.key == K_RIGHT:
                    demo.b += 10
                    demo = PythagoreanTheorem()
                elif event.key == K_LEFT and demo.b > 50:
                    demo.b -= 10
                    demo = PythagoreanTheorem()
        
        # 更新演示
        demo.update()
        
        # 绘制
        demo.draw(screen)
        
        # 更新显示
        pygame.display.flip()
        
        # 控制帧率
        clock.tick(FPS)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()